package com.example.drug.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.hutool.core.util.RandomUtil;

import com.example.common.entity.MsgConfig;
import com.example.common.entity.Pharmacist;
import com.example.common.support.ApiException;
import com.example.common.utils.CheckUtils;
import com.example.common.utils.SmsUtils;
import com.example.drug.dto.req.GetUserInfoReq;
import com.example.drug.dto.req.GetWxInfoReq;
import com.example.drug.jpa.MsgConfigRepository;
import com.example.drug.jpa.PharmacistRepository;
import com.example.drug.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {
    @Resource
    private PharmacistRepository pharmacistRepository;
    @Resource
    private MsgConfigRepository msgConfigRepository;

    @Value("${appID}")
    private String appID;

    @Value("${appsecret}")
    private String appsecret;
    
    @Override
    public HashMap<String, Object> GetUserInfo(GetUserInfoReq ph) {
        Pharmacist obj = pharmacistRepository.findByphone(ph.getPhone());
        CheckUtils.checkNull(obj, new ApiException(10000, "该用户不存在"));

/*        if (new Date().after(obj.getCodeTime())) {
            throw new ApiException(10000, "验证码已失效");
        }*/
        // if (!obj.getCode().equals(ph.getCode())) {
        //     throw new ApiException(10000, "验证码错误");
        // }
        if (obj.getDisable()) {
            throw new ApiException(10000, "用户已禁用");
        }

        if (ph.getWXCode() != null && ph.getWXCode().length() > 0 && (obj.getOpenId() == null || obj.getOpenId().length() <= 0)) {
            WxOAuth2AccessToken accessToken;
            WxMpUser wxMpUser;
            WxMpService wxMpService = new WxMpServiceImpl();
            WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
            
            // configStorage.setAppId("wxe67aedefe4548889");//TODO
            // configStorage.setSecret("8b0c36c3911cc997e0dc0ab6bd0c28f4");//TODO
            configStorage.setAppId("wxe7c13b6fc4c65474");//TODO
            configStorage.setSecret("afbd7422d4a45b8cc0fa440c5227e8ad");//TODO
            wxMpService.setWxMpConfigStorage(configStorage);

            try {
                accessToken = wxMpService.getOAuth2Service().getAccessToken(ph.getWXCode());
                wxMpUser = wxMpService.getUserService()
                        .userInfo(accessToken.getOpenId(), "zh_CN");
                //保存用户信息
                obj.setOpenId(accessToken.getOpenId());
                pharmacistRepository.save(obj);

            } catch (WxErrorException e) {
                log.error(e.getMessage());
            }
        } 

        if(obj.getOpenId() == null || obj.getOpenId().length() <= 0){
            throw new ApiException(10000, "请在手机端认证");
        }

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("DCID", obj.getDcId());
        hashMap.put("Phone", obj.getPhone());
        return hashMap;
    }

    @Override
    public String GetUserTel(GetUserInfoReq ph) {
        Pharmacist obj = pharmacistRepository.findByphone(ph.getPhone());

        CheckUtils.checkNull(obj, new ApiException(10000, "该用户不存在"));
        if (obj.getDisable()) {
            CheckUtils.checkNull(null, new ApiException(10000, "用户已禁用"));
        }

        String phoneCode = RandomUtil.randomNumbers(6);
        MsgConfig config = msgConfigRepository.findById("Pharmacist_Login").orElseThrow(() -> new ApiException(400, "未配置短信模板"));

        SmsUtils.sendSmsMessage(ph.getPhone(), Collections.singletonList(phoneCode), config.getTemplateId());

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + 5);

        obj.setCodeTime(calendar.getTime());
        obj.setCode(phoneCode);
        pharmacistRepository.save(obj);

        return "发送成功";
    }

    //#region 小程序
    
    @Value("${mappID}")
    private String mappID;

    @Value("${mappsecret}")
    private String mappsecret;

    @Override
    public HashMap<String, Object> getWxInfoR(GetUserInfoReq ph) {
        //获取openid
        WxMaService wxService = new WxMaServiceImpl();
        WxMaDefaultConfigImpl wxMaDefaultConfig = new WxMaDefaultConfigImpl();
        wxMaDefaultConfig.setAppid(mappID);//TODO
        wxMaDefaultConfig.setSecret(mappsecret);////TODO
        wxService.setWxMaConfig(wxMaDefaultConfig);
        List<String> tids = msgConfigRepository.findByType();
        try {
            HashMap<String, Object> hashMap = new HashMap<>();
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(ph.getCode());
            Pharmacist obj = pharmacistRepository.findByOpenId(session.getOpenid());
            if(obj == null){
                hashMap.put("OpenID", session.getOpenid());
                hashMap.put("LoginSess", false);
                hashMap.put("tmplIds", tids);
                return hashMap;
            }
            if (obj.getDisable()) {
                throw new ApiException(10000, "用户已禁用");
            }

            hashMap.put("Phone", obj.getPhone());
            hashMap.put("DCID", obj.getDcId());
            hashMap.put("Head", obj.getHead());
            hashMap.put("Name", obj.getName());
            hashMap.put("openId", obj.getOpenId());
            hashMap.put("tmplIds", tids);
            hashMap.put("LoginSess", true);
            return hashMap;
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public HashMap<String, Object> GetUserTelR(GetWxInfoReq ph) {
        WxMaService wxService = new WxMaServiceImpl();
        WxMaDefaultConfigImpl wxMaDefaultConfig = new WxMaDefaultConfigImpl();
        wxMaDefaultConfig.setAppid(mappID);
        wxMaDefaultConfig.setSecret(mappsecret);
        wxService.setWxMaConfig(wxMaDefaultConfig);
        WxMaJscode2SessionResult session = null;
        try {
            session = wxService.getUserService().getSessionInfo(ph.getCode());
        } catch (WxErrorException e) {
            e.printStackTrace();
        }
        WxMaPhoneNumberInfo phoneNoInfo = null;
        try {            
            phoneNoInfo = wxService.getUserService().getPhoneNoInfo(session.getSessionKey(), ph.getEncryptedData(), ph.getIv());            
        } catch (Exception e) {
            throw new ApiException(10000, "授权失败，请重新授权");
        }
        Pharmacist obj = pharmacistRepository.findByphone(phoneNoInfo.getPurePhoneNumber());
        HashMap<String, Object> hashMap = new HashMap<>();
        if (obj == null) {
            throw new ApiException(10000, "该手机号未注册，请联系信息科");  
        }
        if (obj.getDisable()) {
            throw new ApiException(10000, "用户已禁用"); 
        }

        if (obj.getOpenId() == null || obj.getOpenId().length() <= 0 || !obj.getOpenId().equals(session.getOpenid())) {
            obj.setOpenId(session.getOpenid());
            pharmacistRepository.save(obj);
        }

        hashMap.put("Phone", obj.getPhone());
        hashMap.put("DCID", obj.getDcId());
        hashMap.put("Head", obj.getHead());
        hashMap.put("Name", obj.getName());
        hashMap.put("openId", obj.getOpenId());
        hashMap.put("LoginSess", true);
        return hashMap;
    }
    //#endregion
}
